package oop.ex1.actions;
import java.io.*;
import java.util.*;
import java.text.*;

import oop.ex1.filters.*;

/**
 * this class contains all actions described in this exercise.
 * @author miron_6 & dawn16889
 */
public class Action {

	/**
	 * this class prints file information to the standard input.
	 */
	public static class PrintData implements Actions{
		
		/**this method sets the printed parameters.
		 * @throws IOException - thrown by getCanonicalPath()
		 */
		public void doAction(File file) throws IOException{
			String hidden= file.isHidden()? "h":"-";
			String writable = file.canWrite()? "w":"-";
			String executable = file.canExecute()? "x":"-";
			double size = (double)file.length()/128;
			String date = Filters.dateConveLong(file.lastModified()).toString();
			String path = new String(file.getCanonicalPath());
			System.out.println(hidden+writable+executable+" "+size+" "+date+" "+path);
		}
	}
	
	/**
	 * this class prints file name to the standard input.
	 */
	public static class PrintName implements Actions{
		
		/**
		 * this method prints the file name. 
		 */
		public void doAction(File file){
			System.out.println(file.getName());
		
		}
	}
	
	/**
	 * this class copies a file to the given target directory.
	 */
	public static class Copy implements Actions{ 
		String path;
		
		/**
		 * class constructor.
		 * @param path - the name of the new directory we need to create 
		 * @param sourceDir - the directory that the files are copied to
		 * @throws ActionException - if the name of the path is not accurate
		 */
		public Copy(String path, String sourceDir) throws ActionException{
			if (path.startsWith("/"))
				throw new ActionException();
			
			this.path = sourceDir+"/"+path;
		}
		
		/**
		 * this class copies a file from one directory to another.
		 */
		public void doAction(File file) throws CantReadFileException{
			//checks if there is reading permission and if not, throws the correct exception
			if (!file.canRead())
				throw new CantReadFileException("Error");
			//creates the directories that the file is copied to
			new File(path).mkdirs();
			File tempFile = new File(path +"/"+ file.getName());
			//
			OutputStream out = null;
			InputStream in = null;
			try{
				out = new FileOutputStream(tempFile);
				in = new FileInputStream(file.getAbsolutePath());
				int check;
				while((check = in.read()) != -1)
					out.write(check);
			}
			catch(IOException ioe){
				System.err.println("couldn't copy file");
			}
			finally{
				try{
					if(in != null)
						in.close();				
				}
				catch(IOException e){
					System.err.println("couldn't close in");
				}
				try{
					if (out!= null)
						out.close();
				}
				catch(IOException e){
					System.err.println("couldn't close out");
				}
			}
		}
	}
	
	/**
	 * this class sets file executing permission.
	 */
	public static class Exec implements Actions{
		boolean execute;
		
		/**class constructor.
		 * @param execute - a parameter that decides what the executing permissions should be
		 * @throws YesNoException - if the given string is neither YES nor NO
		 */
		public Exec(String execute) throws YesNoException{
			this.execute =Filters.yesNoBool(execute);
		}
		
		/**
		 * this method sets the file to be ,or not to be executable.
		 */
		public void doAction(File file){
			file.setExecutable(execute);
		}
	}
	

	/**
	 * this class sets file writing permission.
	 */
	public static class Write implements Actions{
		boolean writer;
		
		/**class constructor.
		 * @param writer - a parameter that decides what the writing permissions should be
		 * @throws YesNoException - if the given string is neither YES nor NO
		 */
		public Write(String writer) throws YesNoException{
			this.writer = Filters.yesNoBool(writer);
		}
		
		/**
		 * this method sets the file to be ,or not to be writable.
		 */
		public void doAction(File file){
			file.setWritable(writer);
		}
	}
	
	/**
	 * this class sets file's last modified time.
	 */
	public static class LastMod implements Actions{
		Date date;
		
		/**class constructor. parses date represented as string type to date type. 
		 * @param date- the Date parameter.
		 * @throws IllegalDateException - if the date is in an illegal form
		 */
		public LastMod(String date) throws IllegalDateException {
			try{ 
				SimpleDateFormat temp= new SimpleDateFormat("dd/MM/yyyy");
				this.date = temp.parse(date);
			}
			catch (ParseException e) {
				throw new IllegalDateException(e.getMessage(), e.getErrorOffset());
			}
		}
		
		/**
		 * this method sets the file last modified. 
		 */
		public void doAction(File file){
			file.setLastModified(date.getTime());
		}
			
	}
}
